package osami.communication;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Properties;
import java.util.Random;

/**
 * Settings class stores settings of the osami node. It also has functionality
 * to save and load these settings to/from a file.
 * 
 * @author osami
 *
 */
public class Settings
{
	private static Settings iInstance = null;
	private Properties iProperties = null;

	public static final String OSAMI_NODE_ID = "OSAMI_NODE_ID";
	public static final String QUERY_PROXY = "QUERY_PROXY";
	public static final String TCP_IP_ENABLED = "TCP_IP_ENABLED";
	public static final String BLUETOOTH_ENABLED = "BLUETOOTH_ENABLED";
	public static final String TCP_IP_MULTICAST = "TCP_IP_MULTICAST";
	public static final String BLUETOOTH_MULTICAST = "BLUETOOTH_MULTICAST";
	
	private Settings()
	{
		try
		{
			init();
		}
		catch( IOException exception )
		{
			System.out.println( "Settings.Settings: ERROR: " );
			exception.printStackTrace();
		}
	}
	
	/**
	 * Tries to load the properties from a osami.properties file in the user's home directory.
	 * If the file is not found, it will be created with default settings.
	 * 
	 * @throws IOException
	 */
	private void init() throws IOException
	{
		try
		{
			// retrieve data from the properties file
			iProperties = new Properties();
			iProperties.load( new FileInputStream( System.getProperty( "user.home" ) + "/osami.properties" ) );
		}
		catch ( FileNotFoundException exception )
		{
			// if the properties file is not found, it will be created
			create();
		}
	}
	
	/**
	 * Creates the properties-file with default settings.
	 * 
	 * @throws FileNotFoundException
	 */
	private void create() throws FileNotFoundException
	{
		PrintWriter output = new PrintWriter( new FileOutputStream( System.getProperty( "user.home" ) + "/osami.properties" ) );

		try
		{
			output.println( OSAMI_NODE_ID + " = " + new Random().nextInt() );
			output.println( QUERY_PROXY + " = true" );
			output.println( TCP_IP_ENABLED + " = true" );
			output.println( BLUETOOTH_ENABLED + " = true" );
			output.println( TCP_IP_MULTICAST + " = true" );
			output.println( BLUETOOTH_MULTICAST + " = true" );
		}
		finally
		{
			output.close();
		}
	}
	
	/**
	 * Stores the settings into the properties-file.
	 * 
	 * @throws IOException
	 */
	public void store() throws IOException
	{
		PrintWriter output = new PrintWriter( new FileOutputStream( System.getProperty( "user.home" ) + "/osami.properties" ) );
		
		iProperties.store( output, "OSAMI node settings" );
	}

	/**
	 * Return's the singleton settings instance.
	 * 
	 * @return Settings
	 */
	public static Settings getInstance()
	{
		if ( iInstance == null )
			iInstance = new Settings();
		
		return iInstance;
	}
	
	/**
	 * Returns a property's value based on the given key.
	 * 
	 * @param aKey
	 * @return String
	 */
	public String getValue( String aKey )
	{
		String value = iProperties.getProperty( aKey );
		
		if ( value == null )
			System.out.println( "ERROR! Property not found from osami.properties file!" );
		
		return value;
	}
	
	/**
	 * Set's a property key-value pair.
	 * 
	 * @param aKey
	 * @param aValue
	 */
	public void setValue( String aKey, String aValue )
	{
		iProperties.setProperty( aKey, aValue );
	}
	
	/**
	 * Returns a string representation of the settings object.
	 * 
	 */
	public String toString()
	{
		return OSAMI_NODE_ID + 			" = " + getValue( OSAMI_NODE_ID ) + "\n" +
				QUERY_PROXY + 			" = " + getValue( QUERY_PROXY ) + "\n" +
				TCP_IP_ENABLED + 		" = " + getValue( TCP_IP_ENABLED ) + "\n" +
				BLUETOOTH_ENABLED + 	" = " + getValue( BLUETOOTH_ENABLED ) + "\n" +
				TCP_IP_MULTICAST + 		" = " + getValue( TCP_IP_MULTICAST ) + "\n" +
				BLUETOOTH_MULTICAST + 	" = " + getValue( BLUETOOTH_MULTICAST ) + "\n";
	}
}
